package com.processmining.controller;


import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.github.pagehelper.PageInfo;
import com.mysql.fabric.Response;
import com.processmining.entity.Log;
import com.processmining.entity.RawLog;
import com.processmining.entity.User;
import com.processmining.service.INormLogService;
import com.processmining.service.IRawLogService;
import com.processmining.service.IUserService;
import com.processmining.util.exception.FileSizeException;
import com.processmining.util.request.IdList;
import com.processmining.util.request.NormalizeData;
import com.processmining.util.response.Code;
import com.processmining.util.response.ResponseData;
import com.processmining.util.response.ResponseWithListPage;


/**
 * 日志管理--原始日志控制器层
 * @author hxuhao
 *
 */

@Controller
@RequestMapping(value="/rawLog")
public class RawLogController {
	
	@Autowired
	private IRawLogService rawLogService; 
	
	@Autowired
	private INormLogService normLogService;
	
	@Autowired
	private IUserService userService;

	@ResponseBody
	@RequestMapping(value="/init/{id}",method=RequestMethod.GET)
	public String init(@PathVariable("id")Integer id,HttpSession session){
		User user = userService.getUserById(id);
		session.setAttribute("user", user);
		return "init fin";
	}
	
	
	/**
	 * 上传原始日志文件
	 * @param rawLogFile	原始日志
	 * @param format		日志格式
	 * @param shared		是否共享
	 * @param request		
	 * @return
	 * @throws Exception 
	 */
	@ResponseBody
	@RequestMapping(method=RequestMethod.POST)
	public ResponseData uploadRawLog(
			@RequestParam(value="file",required=true) MultipartFile rawLogFile,
			@RequestParam(value="format",required=true) String format,
			@RequestParam(value="shared",required=true) int shared,
			HttpSession session) throws Exception{
		
		if(rawLogFile.getSize()==0){
			throw new FileSizeException("原始日志大小为0");
		}
		
		User user = (User) session.getAttribute("user");
		ResponseData responseData = new ResponseData();
		Log log = new RawLog();
		log.setCreatorid(user.getId());
		log.setFormat(format);
		log.setIsshared(shared==1?true:false);
		log.setName(rawLogFile.getOriginalFilename());
		
		InputStream input = null;


		input = rawLogFile.getInputStream();
		if(rawLogService.uploadLog(input, log)){
			responseData.setCode(Code.SUCCEED);
		}else{
			responseData.setCode(Code.UNKNOWN_FAULT);
		}



		return responseData;
		
	}
	
	

	/**
	 * 下载原始日志，浏览器弹窗
	 * @param logId		原始日志id
	 * @param response
	 */
	@RequestMapping(value="/{rawlogId}",
			produces="application/octet-stream;charset=UTF-8",
			method=RequestMethod.GET)
	public void downloadRawLog(
			@PathVariable(value="rawlogId")Integer logId,
			HttpServletResponse response){
		
		RawLog log = (RawLog) rawLogService.selectByPK(logId);
		byte[] data;
		InputStream input = null;
		try {
			input = rawLogService.downloadLog(logId);
			StringBuilder sb = new StringBuilder();
			BufferedReader reader = new BufferedReader(new InputStreamReader(input, "utf-8"));
			String line ;
			while((line = reader.readLine())!=null){
				sb.append(line+"\r\n");
			}
			data = sb.toString().getBytes();
			
			response.reset();
			response.setContentType("charset=UTF-8");   
	        response.setHeader("Content-Disposition", "attachment; filename=" + new String(log.getName().getBytes("utf-8"),"iso-8859-1"));   
	        response.setHeader("Content-Length", String.valueOf(data.length));
	                     
	        OutputStream outputStream = response.getOutputStream();  
		    outputStream.write(data);  
		    outputStream.flush();  
		    outputStream.close();
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				if(input!=null)
					input.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		
	}
	
	/**
	 * 查看一个原始日志
	 * @param id 原始日志id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/search/{id}",method=RequestMethod.GET)
	public RawLog selectOne(@PathVariable(value="id") Integer id){
		
		RawLog log = (RawLog) rawLogService.selectByPK(id);
		return log;
		
	}
	
	/**
	 * 将一个原始日志变为公有
	 * @param rawLogId 原始日志id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/share/{id}",method=RequestMethod.GET)
	public ResponseData shareRawLog(@PathVariable(value="id") Integer rawLogId,HttpSession session){

		ResponseData response = new ResponseData();
		
		User user = (User) session.getAttribute("user");
			if(rawLogService.shareLog(rawLogId, user.getId())){
			response.setCode(Code.SUCCEED);
		}else{
			response.setCode(Code.NOT_PERMISSION);
		}
		
		return response;
		
	}
	
	/**
	 * 将一个原始日志设为私有
	 * @param rawLogId 原始日志id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/unshare/{id}",method=RequestMethod.GET)
	public ResponseData unshareRawLog(@PathVariable(value="id") Integer rawLogId,HttpSession session){
		
		ResponseData response = new ResponseData();
		
		User user = (User) session.getAttribute("user");
		if(rawLogService.unshareLog(rawLogId, user.getId())){
			response.setCode(Code.SUCCEED);
		}else{
			response.setCode(Code.NOT_PERMISSION);
		}
		
		return response;
		
	}
	
	/**
	 * 查看原始日志/搜索
	 * @param pageNum
	 * @param pageSize
	 * @param info
	 * @param session
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/listAll",method=RequestMethod.GET)
	public ResponseWithListPage<RawLog> selectAll(
			@RequestParam(value="pageNum",defaultValue="1")int pageNum,
			@RequestParam(value="pageSize",defaultValue="10")int pageSize,
			@RequestParam(value="info",required=false) String info,
			HttpSession session){
		User u = (User) session.getAttribute("user");
		Integer uid = u==null?1:u.getId();
		System.out.println("info : " + info);
		ResponseWithListPage<RawLog> response = new ResponseWithListPage<>();
		PageInfo<RawLog> logListWithPage = rawLogService.searchByName(pageNum,pageSize,info,uid);
		response.setCode(Code.SUCCEED);
		response.setData(logListWithPage);
		return response;
		
	}
	
	/**
	 * 删除日志文件
	 * @param idList id列表
	 * @return
	 */
	@ResponseBody
	@RequestMapping(method=RequestMethod.DELETE)
	public ResponseData deleteRawLog(@RequestBody IdList idList,HttpSession session){
		ResponseData response = new ResponseData();
		User user = (User) session.getAttribute("user");
		try {
			if(rawLogService.deleteBatch(idList.getIdList(),user.getId())){
				response.setCode(Code.SUCCEED);
			}else{
				response.setCode(Code.UNKNOWN_FAULT);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			response.setCode(Code.UNKNOWN_FAULT);
		} 
		
		return response;
	}
	
	
	// 规范化
	@ResponseBody
	@RequestMapping(value="/convertToNormLog",method=RequestMethod.POST)
	public ResponseData convertToNormLog(@RequestBody NormalizeData normData,HttpSession session){
		

		ResponseData response = new ResponseData();
		
		
		// 提取规范化参数
		Integer id = normData.getId();
		Integer uid = ((User) session.getAttribute("user")).getId();
		System.out.println(uid);
		String formats = normData.getFormats();
		String timeNames = normData.getTimeNames();
		String targetTimeName = normData.getTargetTimeName();
		String dataNames = normData.getDataNames();
		String oriitemSeparator = normData.getOriitemSeparator();
		String orinameValSeparator = normData.getOrinameValSeparator();
		String orinulVal = normData.getOrinulVal();
		String targetitemSeparator = normData.getTargetitemSeparator();
		String targetnameValSeparator = normData.getTargetnameValSeparator();
		String targetnulVal = normData.getTargetnulVal();
		
		try {
			RawLog rawLog = (RawLog) rawLogService.selectByPK(id);
			
			if(rawLog.getCreatorid()==uid){
				// 删除之前已经规范化的日志
				normLogService.deleteIfExist(normData.getId(),uid);
				if(rawLogService.convertToNormLog(id, uid, 
						formats, timeNames,targetTimeName,dataNames, 
						oriitemSeparator, orinameValSeparator, orinulVal, 
						targetitemSeparator, targetnameValSeparator, targetnulVal)){
					response.setCode(Code.SUCCEED);
				}else{
					response.setCode(Code.UNKNOWN_FAULT);
				}
			}else{
				response.setCode(Code.NOT_PERMISSION);
			}
		} catch (Exception e) {
			e.printStackTrace();
			response.setCode(Code.UNKNOWN_FAULT);
		}
		return response;
		
	}
	
	

	  
	/**
	 * 批量下载
	 * @param request
	 * @param response
	 * @param reportId
	 * @return
	 * @throws IOException
	 */
	@ResponseBody
	@RequestMapping(value="/downloadBatch",method=RequestMethod.GET)
	public String downloadBatch(HttpServletRequest request,HttpServletResponse response,
			@RequestParam(value="idList")String ids,HttpSession session) throws IOException{
		
	    String[] idList = ids.split(";");
		
		//User user = (User) session.getAttribute("user");
	    String outFilePath = request.getSession().getServletContext().getRealPath("/");
		String fileName = UUID.randomUUID()+".zip";
	    byte[] buffer = new byte[1024];   
	    try {  
	        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outFilePath+fileName),Charset.forName("UTF-8"));
	        

	        for(int i=0;i<idList.length;i++){
	        	Integer rawLogid = Integer.valueOf(idList[i]);
	            InputStream fis = rawLogService.downloadLog(rawLogid);  
	            out.putNextEntry(new ZipEntry((i+1)+"."+rawLogService.selectByPK(rawLogid).getName()));  
	            //设置压缩文件内的字符编码，不然会变成乱码  
	           
	            int len;  
	            // 读入需要下载的文件的内容，打包到zip文件  
	            while ((len = fis.read(buffer)) > 0) {  
	                out.write(buffer, 0, len);  
	            }  
	            out.closeEntry();  
	            fis.close();  
	        }  
	        out.close();  
	        this.downloadFileHelp(outFilePath,fileName,response);  
	    } catch (Exception e) {  
	     e.printStackTrace();
	    }  
	    return null;  
	}
		
		
	public void downloadFileHelp(String path,String fileName,HttpServletResponse response){  
        response.setCharacterEncoding("utf-8");  
        response.setContentType("multipart/form-data");  
  
        response.setHeader("Content-Disposition", "attachment;fileName="+fileName+".zip");  
        try {  
            File file=new File(path+fileName);  
            System.out.println(file.getAbsolutePath());  
            InputStream inputStream=new FileInputStream(file);  
            OutputStream os=response.getOutputStream();  
            byte[] b=new byte[1024];  
            int length;  
            while((length=inputStream.read(b))>0){  
                os.write(b,0,length);  
            }  
            inputStream.close();  
            file.delete();
            
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
		
	
}
